Skip to content

Conversation

@ahmetsenturk
Copy link
Contributor

@ahmetsenturk ahmetsenturk commented Apr 15, 2025

🚨 Contains DB Migration - Deploy only to TS3

Checklist

General

Server

  • Important: I implemented the changes with a very good performance and prevented too many (unnecessary) and too complex database calls.
  • I strictly followed the principle of data economy for all database calls.
  • I strictly followed the server coding and design guidelines.
  • I added multiple integration tests (Spring) related to the features (with a high test coverage).
  • I added pre-authorization annotations according to the guidelines and checked the course groups for all new REST Calls (security).
  • I documented the Java code using JavaDoc style.

Client

  • Important: I implemented the changes with a very good performance, prevented too many (unnecessary) REST calls and made sure the UI is responsive, even with large data (e.g. using paging).
  • I strictly followed the principle of data economy for all client-server REST calls.
  • I strictly followed the client coding and design guidelines.
  • Following the theming guidelines, I specified colors only in the theming variable files and checked that the changes look consistent in both the light and the dark theme.
  • I added multiple integration tests (Jest) related to the features (with a high test coverage), while following the test guidelines.
  • I added authorities to all new routes and checked the course groups for displaying navigation elements (links, buttons).
  • I documented the TypeScript code using JSDoc style.
  • I added multiple screenshots/screencasts of my UI changes.
  • I translated all newly inserted strings into English and German.

Motivation and Context

Currently, students have no option to adapt the automated feedback they receive from Athena. The system takes the submission and the solution into account and generates feedback. This PR sets the foundation to introduce personalized feedback generation by:

  • adding feedback preference attributes to the learner profile
  • adding an interface to set up those preferences on settings
  • saving these attributes to later be used in Athena feedback suggestion API

Description

  • Added 4 new feedback preference related attributes to the Learner Profile table
  • Created an interface to set up those preferences on settings

Steps for Testing

Prerequisites:

  • 1 Student
  1. Log in to Artemis
  2. Navigate to Settings
  3. Select the learner profile section
  4. Adjust the preferences as you wish, then save it
  5. Refresh the page, and observe that the values are the ones that you have set

Testserver States

You can manage test servers using Helios. Check environment statuses in the environment list. To deploy to a test server, go to the CI/CD page, find your PR or branch, and trigger the deployment.

Review Progress

Performance Review

  • I (as a reviewer) confirm that the client changes (in particular related to REST calls and UI responsiveness) are implemented with a very good performance even for very large courses with more than 2000 students.
  • I (as a reviewer) confirm that the server changes (in particular related to database calls) are implemented with a very good performance even for very large courses with more than 2000 students.

Code Review

  • Code Review 1
  • Code Review 2

Manual Tests

  • Test 1
  • Test 2

Test Coverage

Screenshots

Screenshot 2025-04-15 at 17 57 36 Screenshot 2025-04-15 at 17 57 26

Summary by CodeRabbit

  • New Features

    • Introduced a Learner Profile section in user settings, allowing users to customize feedback style preferences across four categories using interactive sliders.
    • Added backend support and REST API endpoints for retrieving and updating learner profile feedback preferences.
    • Implemented localization for the Learner Profile feature in both English and German.
    • Added navigation to the Learner Profile settings in the user settings sidebar.
  • Style

    • Added custom styles for the learner profile settings component, including enhanced slider appearance and responsive layout.
  • Documentation

    • Updated localization files with new keys and descriptions for the Learner Profile section.

@ahmetsenturk ahmetsenturk requested review from a team and krusche as code owners April 15, 2025 14:52
@helios-aet helios-aet bot temporarily deployed to artemis-test3.artemis.cit.tum.de April 15, 2025 14:52 Inactive
@github-project-automation github-project-automation bot moved this to Work In Progress in Artemis Development Apr 15, 2025
@github-actions github-actions bot added server Pull requests that update Java code. (Added Automatically!) client Pull requests that update TypeScript code. (Added Automatically!) database Pull requests that update the database. (Added Automatically!). Require a CRITICAL deployment. atlas Pull requests that affect the corresponding module core Pull requests that affect the corresponding module labels Apr 15, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 15, 2025

Walkthrough

This change introduces a new "Learner Profile" feature for collecting and updating user feedback preferences. On the backend, the LearnerProfile entity is extended with four new feedback-related fields, and a corresponding DTO and REST controller (LearnerProfileResource) are added for API access and updates. On the frontend, a new Angular component, service, route, and UI are implemented to allow users to view and modify their learner profile feedback preferences. Localization files for English and German are updated to support the new UI elements. The change is fully integrated into the user settings navigation.

Changes

File(s) / Path(s) Change Summary
src/main/java/de/tum/cit/aet/artemis/atlas/domain/profile/LearnerProfile.java Added four integer feedback fields with JPA and validation annotations, corresponding getters/setters, and a static entity name.
src/main/java/de/tum/cit/aet/artemis/atlas/dto/LearnerProfileDTO.java Introduced a new DTO record for learner profile feedback fields with a static factory method.
src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java Added a new REST controller with endpoints to get and update learner profile feedback fields for the current user, including validation and error handling.
src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.html Added a new Angular HTML template for the learner profile feedback UI with sliders for four feedback categories.
src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.scss Added SCSS styling for the learner profile feedback UI, including custom slider and button styles.
src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts Added a standalone Angular component for displaying, editing, and saving learner profile feedback preferences.
src/main/webapp/app/core/user/settings/user-settings-container/user-settings-container.component.html Added a navigation link to the learner profile settings page in the user settings sidebar.
src/main/webapp/app/core/user/settings/user-settings.route.ts Added a new child route for the learner profile component under user settings.
src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts Added a new Angular service for interacting with the learner profile API (get and update operations).
src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts Added a new TypeScript DTO class for learner profile feedback fields.
src/main/webapp/i18n/de/learnerProfile.json
src/main/webapp/i18n/en/learnerProfile.json
Added new localization files for learner profile feedback settings in German and English.
src/main/webapp/i18n/de/userSettings.json
src/main/webapp/i18n/en/userSettings.json
Added the "learnerProfile" label to the user settings localization files in German and English.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant LearnerProfileComponent (Angular)
    participant LearnerProfileApiService
    participant Backend API
    participant LearnerProfileResource (REST)
    participant LearnerProfileRepository

    User->>LearnerProfileComponent (Angular): Navigates to Learner Profile Settings
    LearnerProfileComponent (Angular)->>LearnerProfileApiService: getLearnerProfileForCurrentUser()
    LearnerProfileApiService->>Backend API: GET /api/atlas/learner-profiles
    Backend API->>LearnerProfileResource (REST): getLearnerProfile()
    LearnerProfileResource (REST)->>LearnerProfileRepository: findByUser()
    LearnerProfileRepository-->>LearnerProfileResource (REST): LearnerProfile
    LearnerProfileResource (REST)-->>Backend API: LearnerProfileDTO
    Backend API-->>LearnerProfileApiService: LearnerProfileDTO
    LearnerProfileApiService-->>LearnerProfileComponent (Angular): LearnerProfileDTO
    LearnerProfileComponent (Angular)-->>User: Displays profile sliders

    User->>LearnerProfileComponent (Angular): Adjusts sliders, clicks Save
    LearnerProfileComponent (Angular)->>LearnerProfileApiService: putUpdatedLearnerProfile(learnerProfileDTO)
    LearnerProfileApiService->>Backend API: PUT /api/atlas/learner-profiles/{id}
    Backend API->>LearnerProfileResource (REST): updateLearnerProfile()
    LearnerProfileResource (REST)->>LearnerProfileRepository: findByIdAndUser()
    LearnerProfileRepository-->>LearnerProfileResource (REST): LearnerProfile
    LearnerProfileResource (REST)->>LearnerProfileRepository: save(updated LearnerProfile)
    LearnerProfileRepository-->>LearnerProfileResource (REST): updated LearnerProfile
    LearnerProfileResource (REST)-->>Backend API: LearnerProfileDTO
    Backend API-->>LearnerProfileApiService: LearnerProfileDTO
    LearnerProfileApiService-->>LearnerProfileComponent (Angular): LearnerProfileDTO
    LearnerProfileComponent (Angular)-->>User: Shows success or error alert
Loading

Suggested labels

feature, ready for review

Suggested reviewers

  • ardakaraman0
  • raffifasaro
  • krusche

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.

📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0c4649f and b7e4a94.

📒 Files selected for processing (6)
  • src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java (1 hunks)
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.html (1 hunks)
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts (1 hunks)
  • src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts (1 hunks)
  • src/main/webapp/i18n/de/learnerProfile.json (1 hunks)
  • src/main/webapp/i18n/en/learnerProfile.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (6)
  • src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.html
  • src/main/webapp/i18n/en/learnerProfile.json
  • src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java
  • src/main/webapp/i18n/de/learnerProfile.json
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (17)
src/main/java/de/tum/cit/aet/artemis/atlas/domain/profile/LearnerProfile.java (2)

42-61: Consider default values for the new feedback fields

The feedback preference fields are well-defined with appropriate column mapping and validation constraints. However, they don't have default initialization values, which could cause unexpected behavior if accessed before being set.

- private int feedbackPracticalTheoretical;
+ private int feedbackPracticalTheoretical = 3; // default middle value

- private int feedbackCreativeGuidance;
+ private int feedbackCreativeGuidance = 3; // default middle value

- private int feedbackFollowupSummary; 
+ private int feedbackFollowupSummary = 3; // default middle value

- private int feedbackBriefDetailed;
+ private int feedbackBriefDetailed = 3; // default middle value

90-120: Consider adding validation in setters

The setters are simple and follow the standard pattern. However, for better error handling, consider adding validation in the setters to ensure the values comply with the @min(1) and @max(5) constraints.

public void setFeedbackPracticalTheoretical(int feedbackPracticalTheoretical) {
+    if (feedbackPracticalTheoretical < 1 || feedbackPracticalTheoretical > 5) {
+        throw new IllegalArgumentException("Feedback value must be between 1 and 5");
+    }
    this.feedbackPracticalTheoretical = feedbackPracticalTheoretical;
}

This pattern should be applied to all four setter methods.

src/main/webapp/i18n/de/userSettings.json (1)

11-11: Space in "Lerner Profil" may be unnecessary

In German, compound nouns are typically written as a single word. Consider using "Lernerprofil" instead of "Lerner Profil" for better German localization.

- "learnerProfile": "Lerner Profil",
+ "learnerProfile": "Lernerprofil",
src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.scss (2)

14-44: Consider alternatives to ::ng-deep for component styling

The use of ::ng-deep is deprecated and will be removed in a future Angular version. While often necessary for styling Angular Material components, it can lead to future maintenance issues.

Consider these alternatives:

  1. Use component view encapsulation: ViewEncapsulation.None (less preferred)
  2. Create a global theme extension for Material components
  3. Use CSS custom properties defined at the component level and consumed inside

Example for option 3:

:host {
  --slider-thumb-size: 24px;
  --slider-track-height: 8px;
  --slider-primary-color: var(--bs-primary);
}

// Then use these variables in your selectors

61-63: Use theme variables consistently

The hover state uses a hardcoded color (#007bff) with the darken function, while the rest of the styles use CSS variables (var(--bs-primary)).

For consistency, consider:

-        background-color: darken(#007bff, 5%);
+        background-color: darken(var(--bs-primary), 5%);

Or better yet, use a CSS variable for the hover state:

-        background-color: darken(#007bff, 5%);
+        background-color: var(--bs-primary-dark, darken(var(--bs-primary), 5%));
src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts (1)

12-14: Simplify HTTP request URL

The string template literal with empty interpolation can be simplified. Also, consider adding error handling for this HTTP request.

getLearnerProfileForCurrentUser(): Observable<LearnerProfileDTO> {
-    return this.http.get<LearnerProfileDTO>(`${this.resourceUrl}`);
+    return this.http.get<LearnerProfileDTO>(this.resourceUrl);
}
src/main/java/de/tum/cit/aet/artemis/atlas/dto/LearnerProfileDTO.java (1)

8-8: Add validation or documentation for allowed value ranges

The record declaration is clean, but it would be helpful to document the expected range of values for the feedback fields.

- public record LearnerProfileDTO(long id, int feedbackPracticalTheoretical, int feedbackCreativeGuidance, int feedbackFollowupSummary, int feedbackBriefDetailed) {
+ /**
+  * Learner Profile Data Transfer Object. 
+  * Feedback values are expected to be in the range of 1-5, where:
+  * - 1 represents the first preference (practical, creative, follow-up, brief)
+  * - 5 represents the second preference (theoretical, focused, summary, detailed)
+  */
+ public record LearnerProfileDTO(long id, int feedbackPracticalTheoretical, int feedbackCreativeGuidance, int feedbackFollowupSummary, int feedbackBriefDetailed) {
src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts (3)

46-59: Add loading state indicator during save operation

While the component tracks the saving state with isSaving, it doesn't seem to be used in the UI to provide visual feedback to users during the save operation.

Consider adding a loading spinner or disabling the save button while saving:

// In the template (learner-profile.component.html), you should have something like:
// <button [disabled]="isSaving" (click)="save()">
//   <fa-icon *ngIf="!isSaving" [icon]="faSave"></fa-icon>
//   <span *ngIf="isSaving" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span>
//   {{ 'save' | translate }}
// </button>

29-29: Improve documentation for hideTooltip method

The purpose of the hideTooltip method isn't clear. If it's intended to prevent tooltips from showing, this should be documented.

-hideTooltip = () => '';
+// Returns empty string to disable default tooltips on sliders
+hideTooltip = () => '';

47-48: Use type for subscribe callback parameter

For better type safety, specify the type for the updatedProfile parameter in the subscribe callback.

 this.learnerProfileApiService.putUpdatedLearnerProfile(this.learnerProfile).subscribe({
-    next: (updatedProfile: LearnerProfileDTO) => {
+    next: (updatedProfile: LearnerProfileDTO) => {

Note: This is already correctly typed, so I'm approving this part of the code. The type annotation provides good clarity.

src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java (7)

28-30: Consider using an enum for profile value constraints

Using static final integers for MIN and MAX profile values is good, but an enum would provide better type safety and encapsulation of related constants.

-private static final int MIN_PROFILE_VALUE = 1;
-private static final int MAX_PROFILE_VALUE = 5;
+private enum ProfileValueBounds {
+    MIN(1),
+    MAX(5);
+    
+    private final int value;
+    
+    ProfileValueBounds(int value) {
+        this.value = value;
+    }
+    
+    public int getValue() {
+        return value;
+    }
+}

Then update the validation method:

 private void validateProfileField(int value, String fieldName) {
-    if (value < MIN_PROFILE_VALUE || value > MAX_PROFILE_VALUE) {
+    if (value < ProfileValueBounds.MIN.getValue() || value > ProfileValueBounds.MAX.getValue()) {
         throw new BadRequestAlertException(fieldName + " field is outside valid bounds", LearnerProfile.ENTITY_NAME, fieldName.toLowerCase() + "OutOfBounds", true);
     }
 }

47-51: Consider improving error message clarity in validation

The current error message doesn't specify the valid range, which would be useful information for clients.

 private void validateProfileField(int value, String fieldName) {
     if (value < MIN_PROFILE_VALUE || value > MAX_PROFILE_VALUE) {
-        throw new BadRequestAlertException(fieldName + " field is outside valid bounds", LearnerProfile.ENTITY_NAME, fieldName.toLowerCase() + "OutOfBounds", true);
+        throw new BadRequestAlertException(fieldName + " field must be between " + MIN_PROFILE_VALUE + " and " + MAX_PROFILE_VALUE, LearnerProfile.ENTITY_NAME, fieldName.toLowerCase() + "OutOfBounds", true);
     }
 }

53-59: Add more comprehensive API documentation

The GET endpoint lacks JavaDoc comments that describe what the method does, unlike the PUT endpoint which has detailed documentation.

+/**
+ * GET /learner-profiles : get the {@link LearnerProfile} for the current user.
+ *
+ * @return A ResponseEntity with status 200 (OK) and the current user's learner profile,
+ *         or an error response if the profile cannot be found.
+ */
 @GetMapping("learner-profiles")
 @EnforceAtLeastStudent
 public ResponseEntity<LearnerProfileDTO> getLearnerProfile() {

72-81: Consider consolidating validation checks

The method has multiple separate validation checks. Consider consolidating them for better readability and maintainability.

-if (learnerProfileDTO.id() != learnerProfileId) {
-    throw new BadRequestAlertException("Provided learnerProfileId does not match learnerProfile.", LearnerProfile.ENTITY_NAME, "objectDoesNotMatchId", true);
-}
-
-Optional<LearnerProfile> optionalLearnerProfile = learnerProfileRepository.findByUser(user);
-
-if (optionalLearnerProfile.isEmpty()) {
-    throw new BadRequestAlertException("LearnerProfile not found.", LearnerProfile.ENTITY_NAME, "LearnerProfileNotFound", true);
-}
+// Validate request integrity
+if (learnerProfileDTO.id() != learnerProfileId) {
+    throw new BadRequestAlertException("Provided learnerProfileId does not match learnerProfile.", LearnerProfile.ENTITY_NAME, "objectDoesNotMatchId", true);
+}
+
+// Fetch and validate learner profile existence
+LearnerProfile updateProfile = learnerProfileRepository.findByUser(user)
+    .orElseThrow(() -> new BadRequestAlertException("LearnerProfile not found.", LearnerProfile.ENTITY_NAME, "LearnerProfileNotFound", true));

83-86: Consider using a batch validation approach

The validation calls are repetitive. Consider using a more elegant approach to validate all fields.

-validateProfileField(learnerProfileDTO.feedbackPracticalTheoretical(), "FeedbackPracticalTheoretical");
-validateProfileField(learnerProfileDTO.feedbackCreativeGuidance(), "FeedbackCreativeGuidance");
-validateProfileField(learnerProfileDTO.feedbackFollowupSummary(), "FeedbackFollowupSummary");
-validateProfileField(learnerProfileDTO.feedbackBriefDetailed(), "FeedbackBriefDetailed");
+// Validate all feedback fields
+Map<String, Integer> fieldsToValidate = Map.of(
+    "FeedbackPracticalTheoretical", learnerProfileDTO.feedbackPracticalTheoretical(),
+    "FeedbackCreativeGuidance", learnerProfileDTO.feedbackCreativeGuidance(),
+    "FeedbackFollowupSummary", learnerProfileDTO.feedbackFollowupSummary(),
+    "FeedbackBriefDetailed", learnerProfileDTO.feedbackBriefDetailed()
+);
+
+fieldsToValidate.forEach(this::validateProfileField);

Remember to update the validateProfileField method signature to accept these parameters.


88-92: Consider using a builder pattern or mapping utility

The manual setting of each field is verbose and error-prone. Consider using a mapping utility or builder pattern.

-LearnerProfile updateProfile = optionalLearnerProfile.get();
-updateProfile.setFeedbackPracticalTheoretical(learnerProfileDTO.feedbackPracticalTheoretical());
-updateProfile.setFeedbackCreativeGuidance(learnerProfileDTO.feedbackCreativeGuidance());
-updateProfile.setFeedbackFollowupSummary(learnerProfileDTO.feedbackFollowupSummary());
-updateProfile.setFeedbackBriefDetailed(learnerProfileDTO.feedbackBriefDetailed());
+// Update learner profile fields
+updateProfile = updateLearnerProfileFromDTO(updateProfile, learnerProfileDTO);

// Add this method to the class:
+/**
+ * Updates a LearnerProfile entity with values from DTO
+ *
+ * @param profile The existing profile to update
+ * @param dto The DTO containing new values
+ * @return The updated profile
+ */
+private LearnerProfile updateLearnerProfileFromDTO(LearnerProfile profile, LearnerProfileDTO dto) {
+    profile.setFeedbackPracticalTheoretical(dto.feedbackPracticalTheoretical());
+    profile.setFeedbackCreativeGuidance(dto.feedbackCreativeGuidance());
+    profile.setFeedbackFollowupSummary(dto.feedbackFollowupSummary());
+    profile.setFeedbackBriefDetailed(dto.feedbackBriefDetailed());
+    return profile;
+}

93-96: Consider adding transaction management

While saving to the repository, it's a good practice to ensure the operation is handled within a transaction.

+import org.springframework.transaction.annotation.Transactional;

// In the method signature:
+@Transactional
 public ResponseEntity<LearnerProfileDTO> updateLearnerProfile(@PathVariable long learnerProfileId, @RequestBody LearnerProfileDTO learnerProfileDTO) {

However, note that the coding guidelines mention "avoid_transactions", so this suggestion might need further discussion to understand if transactions are handled at a different layer in this application.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 91466eb and 0c4649f.

⛔ Files ignored due to path filters (2)
  • src/main/resources/config/liquibase/changelog/20250409191359_changelog.xml is excluded by !**/*.xml
  • src/main/resources/config/liquibase/master.xml is excluded by !**/*.xml
📒 Files selected for processing (14)
  • src/main/java/de/tum/cit/aet/artemis/atlas/domain/profile/LearnerProfile.java (4 hunks)
  • src/main/java/de/tum/cit/aet/artemis/atlas/dto/LearnerProfileDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java (1 hunks)
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.html (1 hunks)
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.scss (1 hunks)
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts (1 hunks)
  • src/main/webapp/app/core/user/settings/user-settings-container/user-settings-container.component.html (1 hunks)
  • src/main/webapp/app/core/user/settings/user-settings.route.ts (1 hunks)
  • src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts (1 hunks)
  • src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts (1 hunks)
  • src/main/webapp/i18n/de/learnerProfile.json (1 hunks)
  • src/main/webapp/i18n/de/userSettings.json (1 hunks)
  • src/main/webapp/i18n/en/learnerProfile.json (1 hunks)
  • src/main/webapp/i18n/en/userSettings.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
`src/main/webapp/i18n/de/**/*.json`: German language translations should be informal (dutzen) and should never be formal (sietzen). So the user should always be addressed with "du/...

src/main/webapp/i18n/de/**/*.json: German language translations should be informal (dutzen) and should never be formal (sietzen). So the user should always be addressed with "du/dein" and never with "sie/ihr".

  • src/main/webapp/i18n/de/learnerProfile.json
  • src/main/webapp/i18n/de/userSettings.json
`src/main/webapp/**/*.html`: @if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

src/main/webapp/**/*.html: @if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

  • src/main/webapp/app/core/user/settings/user-settings-container/user-settings-container.component.html
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.html
`src/main/webapp/**/*.ts`: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalC...

src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

  • src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts
  • src/main/webapp/app/core/user/settings/user-settings.route.ts
  • src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts
`src/main/java/**/*.java`: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,de...

src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

  • src/main/java/de/tum/cit/aet/artemis/atlas/dto/LearnerProfileDTO.java
  • src/main/java/de/tum/cit/aet/artemis/atlas/domain/profile/LearnerProfile.java
  • src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java
🧬 Code Graph Analysis (3)
src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts (1)
src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts (1)
  • LearnerProfileDTO (1-21)
src/main/java/de/tum/cit/aet/artemis/atlas/dto/LearnerProfileDTO.java (1)
src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts (1)
  • LearnerProfileDTO (1-21)
src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts (1)
src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts (1)
  • LearnerProfileDTO (1-21)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Build and Push Docker Image / Build Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build Docker Image for ls1intum/artemis
  • GitHub Check: Build .war artifact
  • GitHub Check: Analyse
  • GitHub Check: client-tests
  • GitHub Check: server-tests
🔇 Additional comments (7)
src/main/java/de/tum/cit/aet/artemis/atlas/domain/profile/LearnerProfile.java (1)

32-32: Good addition of entity name constant

Adding the entity name as a constant provides consistency for logging and error messages. This follows good practice for entity classes.

src/main/webapp/app/core/user/settings/user-settings-container/user-settings-container.component.html (1)

25-25: Appropriately placed navigation item

The new learner profile link is appropriately positioned in the navigation menu between the account information and notification settings links. The HTML follows the established pattern and uses the correct translation key.

src/main/webapp/i18n/en/userSettings.json (1)

11-11: Consistent with user settings terminology

The English translation for "learnerProfile" follows the capitalization pattern of other settings entries (like "Account Information"). The translation is clear and appropriately describes the feature.

src/main/webapp/app/core/user/settings/user-settings.route.ts (1)

28-34: Route implementation looks good!

The new 'profile' route correctly follows Angular best practices with proper lazy loading, consistent with the project's pattern. The route structure and naming are clear and aligned with existing routes.

src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts (1)

1-21: Model implementation is clean and well-structured

The LearnerProfileDTO class is properly defined with appropriate property names following camelCase convention. The default values (3 for preferences) provide a sensible middle value for initialization.

src/main/webapp/i18n/en/learnerProfile.json (1)

1-36: LGTM: Well-structured localization file

The localization structure follows good practices with clear hierarchical organization and comprehensive coverage of all UI elements.

src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java (1)

36-39: LGTM - Good use of constructor injection

The class properly uses constructor injection for dependencies, which follows Spring best practices and the provided Java coding guidelines.

@github-project-automation github-project-automation bot moved this from Work In Progress to Ready For Review in Artemis Development Apr 15, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Apr 15, 2025

Walkthrough

This change introduces a new learner profile feature to the application. It adds a domain entity with feedback preference fields, a corresponding DTO, and a REST API for retrieving and updating the learner profile for the current user. On the frontend, it implements an Angular component and service for displaying and editing learner profile preferences, including UI elements such as sliders and localized text in both English and German. Routing and navigation are updated to include the new learner profile settings page, and associated SCSS styles are provided.

Changes

File(s) / Path(s) Change Summary
src/main/java/de/tum/cit/aet/artemis/atlas/domain/profile/LearnerProfile.java Added four integer feedback fields with validation, corresponding getters/setters, and a static ENTITY_NAME constant to the LearnerProfile entity.
src/main/java/de/tum/cit/aet/artemis/atlas/dto/LearnerProfileDTO.java Introduced new DTO record LearnerProfileDTO with feedback fields and a static factory method for converting from the domain entity.
src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java Added new REST controller with endpoints to get and update the current user's learner profile, including validation and error handling.
src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.html
.../learner-profile.component.scss
.../learner-profile.component.ts
Added new Angular component for learner profile settings, including HTML template, SCSS styles, and TypeScript logic for fetching, displaying, and updating feedback preferences.
src/main/webapp/app/core/user/settings/user-settings-container/user-settings-container.component.html
.../user-settings.route.ts
Updated user settings navigation and routing to include the learner profile settings page.
src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts Added Angular service to handle HTTP requests for retrieving and updating learner profile data.
src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts Added TypeScript class LearnerProfileDTO as the frontend model for learner profile feedback data.
src/main/webapp/i18n/en/learnerProfile.json
.../en/userSettings.json
.../de/learnerProfile.json
.../de/userSettings.json
Added English and German localization files for learner profile UI text and updated user settings labels.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant LearnerProfileComponent (Angular)
    participant LearnerProfileApiService
    participant Backend REST API
    participant LearnerProfileResource (Controller)
    participant LearnerProfileRepository

    User->>LearnerProfileComponent (Angular): Open Learner Profile Settings
    LearnerProfileComponent->>LearnerProfileApiService: getLearnerProfileForCurrentUser()
    LearnerProfileApiService->>Backend REST API: GET /api/atlas/learner-profiles
    Backend REST API->>LearnerProfileResource: getLearnerProfile()
    LearnerProfileResource->>LearnerProfileRepository: findByUser()
    LearnerProfileRepository-->>LearnerProfileResource: LearnerProfile
    LearnerProfileResource-->>Backend REST API: LearnerProfileDTO
    Backend REST API-->>LearnerProfileApiService: LearnerProfileDTO
    LearnerProfileApiService-->>LearnerProfileComponent: LearnerProfileDTO
    LearnerProfileComponent-->>User: Display profile sliders

    User->>LearnerProfileComponent: Adjust sliders & click Save
    LearnerProfileComponent->>LearnerProfileApiService: putUpdatedLearnerProfile(updated DTO)
    LearnerProfileApiService->>Backend REST API: PUT /api/atlas/learner-profiles/{id}
    Backend REST API->>LearnerProfileResource: updateLearnerProfile()
    LearnerProfileResource->>LearnerProfileRepository: findByIdAndUser()
    LearnerProfileRepository-->>LearnerProfileResource: LearnerProfile
    LearnerProfileResource->>LearnerProfileRepository: save(updated LearnerProfile)
    LearnerProfileRepository-->>LearnerProfileResource: updated LearnerProfile
    LearnerProfileResource-->>Backend REST API: updated LearnerProfileDTO
    Backend REST API-->>LearnerProfileApiService: updated LearnerProfileDTO
    LearnerProfileApiService-->>LearnerProfileComponent: updated LearnerProfileDTO
    LearnerProfileComponent-->>User: Show success message
Loading

Possibly related issues

Suggested labels

feature, user interface, documentation, ready for review

Suggested reviewers

  • krusche
  • HanyangXu0508
  • HawKhiem
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 10

🧹 Nitpick comments (11)
src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.scss (3)

29-36: Consider using theme variables for consistent color management.

The hardcoded color values for the slider track elements could be replaced with theme variables for better consistency with the application's theme system, especially since you're already using var(--bs-primary) for active elements.

-                background-color: #e0e0e0 !important;
+                background-color: var(--bs-light) !important;

This would ensure your component adapts properly to any theme changes in the application.


50-51: Use theme variables for text colors.

Similar to the previous comment, it's better to use theme variables for text colors rather than hardcoded values like #666.

-        color: #666;
+        color: var(--bs-secondary-text);

62-62: Use theme variables instead of hardcoded colors.

Using a hardcoded color and darken function is less maintainable than using theme variables.

-        background-color: darken(#007bff, 5%);
+        background-color: var(--bs-primary-dark, darken(var(--bs-primary), 5%));
src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts (1)

1-21: Consider adding type constraints or documentation for valid ranges.

The model looks well-structured with appropriate naming conventions. However, since these feedback preference fields likely have a valid range (possibly 1-5 based on the UI sliders), it would be helpful to either:

  1. Add documentation about the valid range
  2. Use a more specific type than number to ensure correct usage
+/**
+ * Data Transfer Object for Learner Profile settings
+ * Feedback preferences are on a scale of 1-5, with 3 as the default (neutral) value
+ */
 export class LearnerProfileDTO {
     public id: number;
+    /** Feedback preference from 1 (practical) to 5 (theoretical) */
     public feedbackPracticalTheoretical: number;
+    /** Feedback preference from 1 (creative) to 5 (focused) */
     public feedbackCreativeGuidance: number;
+    /** Feedback preference from 1 (follow-up) to 5 (summary) */
     public feedbackFollowupSummary: number;
+    /** Feedback preference from 1 (brief) to 5 (detailed) */
     public feedbackBriefDetailed: number;
src/main/webapp/i18n/en/learnerProfile.json (1)

5-5: Ensure description matches the translation scope.

The current description is quite general and doesn't specifically mention feedback preferences like the German translation does. Consider making it more specific to align with the actual purpose of these settings.

-            "description": "Customize your learning experience by adjusting your preferences.",
+            "description": "Customize your learning experience by adjusting your feedback style preferences.",
src/main/java/de/tum/cit/aet/artemis/atlas/dto/LearnerProfileDTO.java (1)

10-19: Consider adding documentation for feedback preference values

The of method is well implemented to convert from the domain entity to the DTO. However, consider adding some JavaDoc comments to explain what each feedback preference field represents and what the scale values (1-5) mean.

 public record LearnerProfileDTO(long id, int feedbackPracticalTheoretical, int feedbackCreativeGuidance, int feedbackFollowupSummary, int feedbackBriefDetailed) {

+    /**
+     * Feedback fields represent user preferences on a scale of 1-5 where:
+     * - feedbackPracticalTheoretical: 1=practical, 5=theoretical
+     * - feedbackCreativeGuidance: 1=creative, 5=guided/focused
+     * - feedbackFollowupSummary: 1=follow-up, 5=summary
+     * - feedbackBriefDetailed: 1=brief, 5=detailed
+     */
+
     /**
      * Creates LearnerProfileDTO from given LearnerProfile.
      *
      * @param learnerProfile The given LearnerProfile
      * @return LearnerProfile DTO for transfer
      */
src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.html (3)

25-32: Standardize binding approach across sliders

The first slider uses separate [value] and (valueChange) bindings while the other sliders (lines 42, 53, 64) use [(ngModel)]. For consistency, use the same approach across all sliders.

<mat-slider min="1" max="5" step="1" [discrete]="true" showTickMarks [displayWith]="hideTooltip">
    <input
        matSliderThumb
-       [value]="learnerProfile.feedbackPracticalTheoretical"
-       (valueChange)="learnerProfile.feedbackPracticalTheoretical = $event"
+       [(ngModel)]="learnerProfile.feedbackPracticalTheoretical"
        (change)="onSliderChange()"
    />
</mat-slider>

25-65: Add accessibility attributes to sliders

The sliders are missing accessibility attributes such as aria-label that would improve user experience for those using assistive technologies.

<mat-slider min="1" max="5" step="1" [discrete]="true" showTickMarks [displayWith]="hideTooltip">
    <input
        matSliderThumb
+       [attr.aria-label]="'artemisApp.learnerProfile.feedback.feedbackPracticalTheoretical.title' | translate"
        [value]="learnerProfile.feedbackPracticalTheoretical"
        (valueChange)="learnerProfile.feedbackPracticalTheoretical = $event"
        (change)="onSliderChange()"
    />
</mat-slider>

33-69: Consider adding numeric indicators for slider values

The sliders show labels for the extremes (1 and 5), but users might benefit from seeing the current numeric value they've selected. Consider adding a visual indicator of the current value.

<div class="labels">
    <span jhiTranslate="artemisApp.learnerProfile.feedback.feedbackPracticalTheoretical.practical"></span>
+   <span class="current-value">{{ learnerProfile.feedbackPracticalTheoretical }}</span>
    <span jhiTranslate="artemisApp.learnerProfile.feedback.feedbackPracticalTheoretical.theoretical"></span>
</div>
src/main/java/de/tum/cit/aet/artemis/atlas/domain/profile/LearnerProfile.java (1)

90-120: Add documentation to feedback getter/setter methods

Consider adding JavaDoc comments to the getter and setter methods to improve code documentation and explain what each preference represents.

+/**
+ * Gets the feedback preference for practical vs theoretical content.
+ * Lower values (1) indicate preference for practical content, higher values (5) for theoretical.
+ * @return feedback preference value between 1-5
+ */
public int getFeedbackPracticalTheoretical() {
    return feedbackPracticalTheoretical;
}

+/**
+ * Sets the feedback preference for practical vs theoretical content.
+ * @param feedbackPracticalTheoretical value between 1-5
+ */
public void setFeedbackPracticalTheoretical(int feedbackPracticalTheoretical) {
    this.feedbackPracticalTheoretical = feedbackPracticalTheoretical;
}
src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java (1)

61-96: Consider reducing duplication in the update operation.

The update method contains redundant code for setting each feedback field. Consider refactoring this to reduce duplication. Additionally, consider adding explicit transaction management for clarity.

+import org.springframework.transaction.annotation.Transactional;

 @PutMapping(value = "learner-profiles/{learnerProfileId}")
 @EnforceAtLeastStudent
+@Transactional
 public ResponseEntity<LearnerProfileDTO> updateLearnerProfile(@PathVariable long learnerProfileId, @RequestBody LearnerProfileDTO learnerProfileDTO) {
     User user = userRepository.getUser();

     if (learnerProfileDTO.id() != learnerProfileId) {
         throw new BadRequestAlertException("Provided learnerProfileId does not match learnerProfile.", LearnerProfile.ENTITY_NAME, "objectDoesNotMatchId", true);
     }

-    Optional<LearnerProfile> optionalLearnerProfile = learnerProfileRepository.findByUser(user);
-
-    if (optionalLearnerProfile.isEmpty()) {
-        throw new BadRequestAlertException("LearnerProfile not found.", LearnerProfile.ENTITY_NAME, "LearnerProfileNotFound", true);
-    }
+    LearnerProfile updateProfile = learnerProfileRepository.findByUserElseThrow(user);

     validateProfileField(learnerProfileDTO.feedbackPracticalTheoretical(), "FeedbackPracticalTheoretical");
     validateProfileField(learnerProfileDTO.feedbackCreativeGuidance(), "FeedbackCreativeGuidance");
     validateProfileField(learnerProfileDTO.feedbackFollowupSummary(), "FeedbackFollowupSummary");
     validateProfileField(learnerProfileDTO.feedbackBriefDetailed(), "FeedbackBriefDetailed");

-    LearnerProfile updateProfile = optionalLearnerProfile.get();
     updateProfile.setFeedbackPracticalTheoretical(learnerProfileDTO.feedbackPracticalTheoretical());
     updateProfile.setFeedbackCreativeGuidance(learnerProfileDTO.feedbackCreativeGuidance());
     updateProfile.setFeedbackFollowupSummary(learnerProfileDTO.feedbackFollowupSummary());
     updateProfile.setFeedbackBriefDetailed(learnerProfileDTO.feedbackBriefDetailed());

     LearnerProfile result = learnerProfileRepository.save(updateProfile);
     return ResponseEntity.ok(LearnerProfileDTO.of(result));
 }
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 91466eb and 0c4649f.

⛔ Files ignored due to path filters (2)
  • src/main/resources/config/liquibase/changelog/20250409191359_changelog.xml is excluded by !**/*.xml
  • src/main/resources/config/liquibase/master.xml is excluded by !**/*.xml
📒 Files selected for processing (14)
  • src/main/java/de/tum/cit/aet/artemis/atlas/domain/profile/LearnerProfile.java (4 hunks)
  • src/main/java/de/tum/cit/aet/artemis/atlas/dto/LearnerProfileDTO.java (1 hunks)
  • src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java (1 hunks)
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.html (1 hunks)
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.scss (1 hunks)
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts (1 hunks)
  • src/main/webapp/app/core/user/settings/user-settings-container/user-settings-container.component.html (1 hunks)
  • src/main/webapp/app/core/user/settings/user-settings.route.ts (1 hunks)
  • src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts (1 hunks)
  • src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts (1 hunks)
  • src/main/webapp/i18n/de/learnerProfile.json (1 hunks)
  • src/main/webapp/i18n/de/userSettings.json (1 hunks)
  • src/main/webapp/i18n/en/learnerProfile.json (1 hunks)
  • src/main/webapp/i18n/en/userSettings.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
`src/main/webapp/i18n/de/**/*.json`: German language translations should be informal (dutzen) and should never be formal (sietzen). So the user should always be addressed with "du/...

src/main/webapp/i18n/de/**/*.json: German language translations should be informal (dutzen) and should never be formal (sietzen). So the user should always be addressed with "du/dein" and never with "sie/ihr".

  • src/main/webapp/i18n/de/userSettings.json
  • src/main/webapp/i18n/de/learnerProfile.json
`src/main/webapp/**/*.ts`: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalC...

src/main/webapp/**/*.ts: angular_style:https://angular.io/guide/styleguide;methods_in_html:false;lazy_loading:true;code_reuse:true;tests:meaningful;types:PascalCase;enums:PascalCase;funcs:camelCase;props:camelCase;no_priv_prefix:true;strings:single_quotes;localize:true;btns:functionality;links:navigation;icons_text:newline;labels:associate;code_style:arrow_funcs,curly_braces,open_braces_same_line,indent_4;memory_leak_prevention:true;routes:naming_schema;chart_framework:ngx-charts;responsive_layout:true

  • src/main/webapp/app/core/user/settings/user-settings.route.ts
  • src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts
  • src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts
`src/main/webapp/**/*.html`: @if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

src/main/webapp/**/*.html: @if and @for are new and valid Angular syntax replacing *ngIf and *ngFor. They should always be used over the old style.

  • src/main/webapp/app/core/user/settings/user-settings-container/user-settings-container.component.html
  • src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.html
`src/main/java/**/*.java`: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,de...

src/main/java/**/*.java: naming:CamelCase; principles:{single_responsibility,small_methods,no_duplication}; db:{perf_queries,datetime_not_timestamp}; rest:{stateless,singleton,delegate_logic,http_only,minimal_dtos}; dtos:{java_records,no_entities,min_data,single_resp}; di:constructor_injection; kiss:simple_code; file_handling:os_indep_paths; practices:{least_access,avoid_transactions,code_reuse,static_member_ref,prefer_primitives}; sql:{param_annotation,uppercase,avoid_subqueries};java:avoid_star_imports

  • src/main/java/de/tum/cit/aet/artemis/atlas/domain/profile/LearnerProfile.java
  • src/main/java/de/tum/cit/aet/artemis/atlas/dto/LearnerProfileDTO.java
  • src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java
🧬 Code Graph Analysis (4)
src/main/java/de/tum/cit/aet/artemis/atlas/dto/LearnerProfileDTO.java (1)
src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts (1)
  • LearnerProfileDTO (1-21)
src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts (1)
src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts (1)
  • LearnerProfileDTO (1-21)
src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts (1)
src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts (1)
  • LearnerProfileDTO (1-21)
src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java (3)
src/main/java/de/tum/cit/aet/artemis/atlas/config/AtlasEnabled.java (1)
  • AtlasEnabled (13-25)
src/main/webapp/app/learner-profile/shared/entities/learner-profile.model.ts (1)
  • LearnerProfileDTO (1-21)
src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts (1)
  • save (41-59)
⏰ Context from checks skipped due to timeout of 90000ms (5)
  • GitHub Check: Build and Push Docker Image / Build Docker Image for ls1intum/artemis
  • GitHub Check: Build and Push Docker Image / Build Docker Image for ls1intum/artemis
  • GitHub Check: Analyse
  • GitHub Check: client-tests
  • GitHub Check: server-tests
🔇 Additional comments (14)
src/main/webapp/app/core/user/settings/user-settings-container/user-settings-container.component.html (1)

25-25: The navigation link looks good

The navigation link for the learner profile is correctly placed and follows the same pattern as other navigation items.

src/main/webapp/i18n/en/userSettings.json (1)

11-11: English translation is correct

The English translation for the learner profile is appropriate and follows the capitalization pattern used in other menu items.

src/main/webapp/app/core/user/settings/user-settings.route.ts (1)

28-34: Route configuration is well-implemented

The route configuration follows Angular best practices with lazy loading and proper naming conventions. The translation key for the page title is correctly referenced.

src/main/webapp/i18n/en/learnerProfile.json (1)

1-36: Well-structured and comprehensive localization entries.

The English translation file provides clear, descriptive text for all UI elements related to learner profile feedback preferences. The explanations of each feedback dimension are informative and will help users understand the purpose of each setting.

src/main/java/de/tum/cit/aet/artemis/atlas/dto/LearnerProfileDTO.java (1)

7-8: Record definition looks good

Using record with @JsonInclude is appropriate for this DTO. The structure aligns well with the TypeScript model in the frontend.

src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.html (1)

1-17: Header layout and save button implementation look good

The implementation of the header with conditional save button using @if (replacing the deprecated *ngIf) is appropriate and follows the guidelines. The save button correctly shows only when changes are detected.

src/main/webapp/app/learner-profile/service/learner-profile-api.service.ts (1)

7-10: Service setup and dependency injection look good

The service is properly set up with @Injectable and the modern inject pattern for HttpClient injection. The resource URL path is appropriate.

src/main/java/de/tum/cit/aet/artemis/atlas/domain/profile/LearnerProfile.java (1)

32-32: Good addition of ENTITY_NAME constant

Adding a constant for the entity name is a good practice for consistency and maintainability.

src/main/webapp/app/core/user/settings/learner-profile/learner-profile.component.ts (2)

1-9: Imports look well-organized and follow Angular standards.

The imports include all necessary modules for Angular forms, translations, Material components, and FontAwesome icons, following the Angular style guide recommendations.


11-17: Component declaration follows Angular best practices.

The component is properly declared as standalone with appropriate imports and follows Angular's style guide for component structure. The selector uses the project's 'jhi-' prefix convention, and stylesheets are properly referenced.

src/main/java/de/tum/cit/aet/artemis/atlas/web/LearnerProfileResource.java (4)

1-22: Good organization of imports and packages.

The imports are well-organized and do not use star imports, which aligns with Java best practices. The code correctly imports necessary classes from appropriate packages.


23-39: Constructor injection is correctly implemented.

The class follows Spring best practices by using constructor injection rather than field injection. The conditional annotation ensures this controller is only active when the Atlas feature is enabled, which is a good approach for feature toggling.


41-51: Validation method is concise and reusable.

The validation method is well-designed with proper constants for min/max values and throws appropriate exceptions with detailed error messages. This encourages code reuse and maintains consistency in validation.


53-59: GET endpoint is secure and follows REST principles.

The endpoint properly enforces student-level access and uses appropriate repository methods. It correctly converts the domain entity to a DTO before returning it, following REST best practices.

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report201 ran197 passed3 skipped1 failed49m 6s 321ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/programming/ProgrammingExerciseStaticCodeAnalysis.spec.ts
ts.Static code analysis tests › Configures SCA grading and makes a successful submission with SCA errors❌ failure1m 44s 883ms

@github-actions
Copy link

End-to-End (E2E) Test Results Summary

TestsPassed ☑️Skipped ⚠️Failed ❌️Time ⏱
End-to-End (E2E) Test Report201 ran197 passed3 skipped1 failed50m 15s 369ms
TestResultTime ⏱
End-to-End (E2E) Test Report
e2e/exercise/programming/ProgrammingExerciseStaticCodeAnalysis.spec.ts
ts.Static code analysis tests › Configures SCA grading and makes a successful submission with SCA errors❌ failure1m 46s 5ms

@ahmetsenturk
Copy link
Contributor Author

ahmetsenturk commented Apr 15, 2025

Closing this as the UI needs to adapt to #10440 as that PR already went over the UI with @rabeatwork.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

atlas Pull requests that affect the corresponding module client Pull requests that update TypeScript code. (Added Automatically!) core Pull requests that affect the corresponding module database Pull requests that update the database. (Added Automatically!). Require a CRITICAL deployment. server Pull requests that update Java code. (Added Automatically!)

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants